/**
 *	@file	np_main.c
 *	@brief	ボングリボックスアプリメイン
 *	@author	Miyuki Iwasawa
 *	@date	08.08.04
 *
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/pmfprint.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "gflib/touchpanel.h"
#include "msgdata/msg.naix"

#include "savedata/config.h"
#include "application/bong_case.h"
#include "bc_sys.h"
#include "bc_app.h"
#include "bc_sub.h"
#include "bc_key.h"
#include "bc_snd_def.h"

//=========================================================
//プロトタイプ定義
//=========================================================
static void app_InitData(BC_APPWORK* wk);
static void app_EndData(BC_APPWORK* wk);
static BOOL app_Init(BC_APPWORK* wk);
static BOOL app_End(BC_APPWORK* wk);

static int seq_FadeIn(BC_APPWORK* wk);
static int seq_FadeOut(BC_APPWORK* wk);
static int seq_1stMsg(BC_APPWORK* wk);
static int seq_NormalMain(BC_APPWORK* wk);
static int seq_PotMain(BC_APPWORK* wk);
static int seq_BallMain(BC_APPWORK* wk);
static int seq_BallNumSet(BC_APPWORK* wk);
static int seq_BongMoveKey(BC_APPWORK* wk);
static int seq_BongMoveTouch(BC_APPWORK* wk);
static int seq_BongMoveEnd(BC_APPWORK* wk);
static int seq_BongPotSet(BC_APPWORK* wk);
static int seq_ListJuice(BC_APPWORK* wk);
static int seq_MsgWait(BC_APPWORK* wk);
static int seq_TalkMsgWait(BC_APPWORK* wk);

static BOOL sub_MsgWait(BC_APPWORK* wk);
static void sub_ViewClear(void);

//=========================================================
//プロセス定義
//=========================================================
/**
 *	@brief	ボングリボックスアプリ呼び出し
 */
PROC_RESULT BongCaseProc_Init(PROC* proc,int* seq)
{

	switch(*seq){
	case 0:
		sub_ViewClear();

		//ヒープ作成
		HeapStatePush();
		sys_CreateHeap(HEAPID_BASE_APP,HEAPID_BONGCASE_APP,0x20000);

		{
			BC_APPWORK* wk = NULL;
			wk = PROC_AllocWork(proc,sizeof(BC_APPWORK),HEAPID_BONGCASE_APP);
			MI_CpuClear8(wk,sizeof(BC_APPWORK));

			wk->heapID = HEAPID_BONGCASE_APP;
			wk->sp = (BC_SYSWORK*)PROC_GetParentWork(proc);

			//引継ぎデータ初期化
			app_InitData(wk);
		}
		(*seq)++;
		break;
	case 1:
		if(app_Init((BC_APPWORK*)PROC_GetWork(proc))){
			return PROC_RES_FINISH;
		}
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	ボングリボックスモジュールメイン
 */
PROC_RESULT BongCaseProc_Main(PROC* proc,int* seq)
{
	BC_APPWORK* wk = (BC_APPWORK*)PROC_GetWork(proc);

	switch(*seq){
	case SEQ_FADE_IN:
		*seq = seq_FadeIn(wk);
		break;
	case SEQ_FADE_OUT:
		*seq = seq_FadeOut(wk);
		break;
	case SEQ_1ST_MSG:
		*seq = seq_1stMsg(wk);
		break;
	case SEQ_NORMAL_MAIN:
		*seq = seq_NormalMain(wk);
		break;
	case SEQ_POT_MAIN:
		*seq = seq_PotMain(wk);
		break;
	case SEQ_BALL_MAIN:
		*seq = seq_BallMain(wk);
		break;
	case SEQ_BALL_NUMSET:
		*seq = seq_BallNumSet(wk);
		break;
	case SEQ_BONG_MOVE_KEY:
		*seq = seq_BongMoveKey(wk);
		break;
	case SEQ_BONG_MOVE_TOUCH:
		*seq = seq_BongMoveTouch(wk);
		break;
	case SEQ_BONG_MOVE_END:
		*seq = seq_BongMoveEnd(wk);
		break;
	case SEQ_BONG_POT_SET:
		*seq = seq_BongPotSet(wk);
		break;
	case SEQ_LIST_JUICE:
		*seq = seq_ListJuice(wk);
		break;
	case SEQ_MSG_WAIT:
		*seq = seq_MsgWait(wk);
		break;
	case SEQ_TALKMSG_WAIT:
		*seq = seq_TalkMsgWait(wk);
		break;
	case SEQ_EXIT:
		return PROC_RES_FINISH;
	}
	CATS_Draw(wk->pActRes);
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	ボングリボックスモジュール終了
 */
PROC_RESULT BongCaseProc_End(PROC* proc,int* seq)
{
	BC_APPWORK* wk = (BC_APPWORK*)PROC_GetWork(proc);

	if(!app_End(wk)){
		return PROC_RES_CONTINUE;
	}
	//引継ぎデータ書き戻し
	app_EndData(wk);

	//ワーク解放
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(HEAPID_BONGCASE_APP);

	sys_DeleteHeap(HEAPID_BONGCASE_APP);

	return PROC_RES_FINISH;
}

////////////////////////////////////////////////////////////////////////
//サブ

/**
 *	@brief	引継ぎデータ初期化
 */
static void app_InitData(BC_APPWORK* wk)
{
	int i;
	CONFIG* config;

	//キーモード初期化
	wk->key_mode = KeyTouchStatus_CheckTouchOrKey(wk->sp->param->kt_status);

	//コンフィグ
	config = SaveData_GetConfig(wk->sp->param->save);
	wk->msg_spd = CONFIG_GetMsgPrintSpeed(config);
	wk->win_type = CONFIG_GetWindowType(config);

	//呼び出しモード初期化
	wk->mode = wk->sp->mode;

	//歩数
	wk->now_walk_ct = wk->sp->param->walk_ct;

	//ぼんぐりセーブデータ取得
	wk->bong_sv = SaveData_GetBonguriSave(wk->sp->param->save);

//	BonguriSave_JuiceStateUpdate(wk->bong_sv,wk->now_walk_ct);

	BCSub_BongDataUpdate(wk);

	//カーソル位置復帰
	if(wk->mode == SYSMODE_PLIST){
		wk->cpos_x = CLINE_C;
		wk->cpos_y = 0;
		wk->opos_a = wk->sp->ret_cpos_a;
		wk->opos_b = wk->sp->ret_cpos_b;

		//モード復帰
		wk->mode = SYSMODE_POT;
		wk->sp->mode = SYSMODE_POT;
	}
}

/**
 *	@brief	引継ぎデータ終了処理
 */
static void app_EndData(BC_APPWORK* wk)
{
	//キーモード書き戻し
	KeyTouchStatus_SetTouchOrKey(wk->sp->param->kt_status,wk->key_mode);
}

/**
 *	@brief	初期化
 *
 */
static BOOL app_Init(BC_APPWORK* wk)
{
	switch(wk->seq){
	case 0:
		BongCaseResInit(wk);
		++wk->seq;
		break;
	case 1:
		BongCaseInitialDraw(wk);

		//タッチパネル初期化
		InitTPSystem();
		InitTPNoBuff(1);

		wk->seq = 0;
		return TRUE;
	}
	return FALSE;

}

/**
 *	@brief	終了処理
 *
 */
static BOOL app_End(BC_APPWORK* wk)
{
	switch(wk->seq){
	case 0:
		//タッチパネル終了
		StopTP();
		BongCaseResRelease(wk);
		++wk->seq;
		break;
	case 1:
	default:
		sub_ViewClear();
		wk->seq = 0;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	フェードイン
 *
 */
static int seq_FadeIn(BC_APPWORK* wk)
{
	switch(wk->seq){
	case 0:
		WIPE_SYS_Start(
			WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN,
			WIPE_TYPE_FADEIN, WIPE_FADE_BLACK, WIPE_DEF_DIV, WIPE_DEF_SYNC, wk->heapID);
		wk->seq++;
		break;
	case 1:
		if( !WIPE_SYS_EndCheck()){
			break;
		}
		wk->seq = 0;

		switch(wk->mode){
		case SYSMODE_POT:
			if(BonguriSave_GetStartupFlag(wk->bong_sv) != BONG_STARTUP_NONE){
				return SEQ_1ST_MSG;
			}
			return SEQ_POT_MAIN;
		case SYSMODE_BALL:
			return SEQ_BALL_MAIN;
		case SYSMODE_NORMAL:
		default:
			return SEQ_NORMAL_MAIN;
		}
	}
	return SEQ_FADE_IN;
}

/**
 *	@brief	フェードアウト
 *
 */
static int seq_FadeOut(BC_APPWORK* wk)
{
	switch(wk->seq){
	case 0:
		WIPE_SYS_Start(
			WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT,
			WIPE_TYPE_FADEOUT, WIPE_FADE_BLACK, WIPE_DEF_DIV, WIPE_DEF_SYNC, wk->heapID);
		wk->seq++;
		break;
	case 1:
		if( !WIPE_SYS_EndCheck()){
			break;
		}
		wk->seq = 0;
		return SEQ_EXIT;
	}
	return SEQ_FADE_OUT;
}

/**
 *	@brief	起動メッセージ表示
 */
static int seq_1stMsg(BC_APPWORK* wk)
{
	int ret;

	switch(wk->seq){
	case 0:
		BCSub_SetPassivePotMain(wk,BONG_STATE_PASSIVE);
		ret = BonguriSave_GetStartupFlag(wk->bong_sv);
		switch(ret){
		case BONG_STARTUP_1ST:
			BCSub_TalkMsgPut(wk,MIDX_TALK_INI_1ST,wk->msg_spd);
			break;
		case BONG_STARTUP_NEW:
			BCSub_TalkMsgPut(wk,MIDX_TALK_INI_NEW,MSG_NO_PUT);
			break;
		case BONG_STARTUP_UPDATE:
			BCSub_TalkMsgPut(wk,MIDX_TALK_INI_UPDATE,MSG_NO_PUT);
			break;
		}
		BonguriSave_SetStartupFlag(wk->bong_sv,BONG_STARTUP_NONE);
		wk->seq++;
		break;
	default:
		if(!sub_MsgWait(wk)){
			break;
		}
		BCSub_SetPassivePotMain(wk,BONG_STATE_ACTIVE);
		BCSub_TalkMsgClear(wk);
		wk->seq = 0;
		return SEQ_POT_MAIN;
	}
	return SEQ_1ST_MSG;
}

/**
 *	@brief	ノーマル画面メイン
 */
static int seq_NormalMain(BC_APPWORK* wk)
{
	int ret;

	ret = BCKey_InputNormalMain(wk);
	return ret;
}
/**
 *	@brief	ポット画面メイン
 */
static int seq_PotMain(BC_APPWORK* wk)
{
	int ret;

	switch(wk->seq){
	case 0:
		BCSub_SetPassivePotMain(wk,BONG_STATE_ACTIVE);
		wk->seq++;
		break;
	case 1:
		ret = BCKey_InputPotMain(wk);
		if( ret != SEQ_POT_MAIN )
		{
			wk->seq	= 0;
		}
		return ret;
	}
	return SEQ_POT_MAIN;
}

/**
 *	@brief	ボール作成画面メイン
 */
static int seq_BallMain(BC_APPWORK* wk)
{
	int ret;

	ret = BCKey_InputBallMain(wk);
	return ret;
}

/**
 *	@brief	ボール作成個数入力画面メイン
 */
static int seq_BallNumSet(BC_APPWORK* wk)
{
	int ret;

	switch(wk->seq){
	case 0:
		BCSub_SetPassivePotMain(wk,BONG_STATE_TARGET_ONLY);
		BCSub_BallSelectScrnWrite(wk,TRUE);
		BCSub_SysMsgPut(wk,MIDX_SYS_BONG02);	//渡す数を選んでください
		wk->seq++;
		break;
	case 1:
		ret = BCKey_InputBallNumSet(wk);
		if(ret == EXE_NSET_NULL){
			break;
		}
		wk->next_seq = ret;
		wk->ct = 4;
		wk->seq++;
		break;
	case 2:
		if(wk->ct-- > 0){
			break;
		}
		if(wk->next_seq == EXE_NSET_CANCEL){
			BCSub_SetPassivePotMain(wk,BONG_STATE_ACTIVE);
			BCSub_BallSelectScrnWrite(wk,FALSE);
			BCSub_SysMsgPut(wk,MIDX_SYS_BONG01);	//渡すぼんぐりを選んでください
			wk->seq = 0;
			return SEQ_BALL_MAIN;
		}
		BCSub_SysMsgPut(wk,MIDX_SYS_BONG03);	//○○をX個でいいですか？
		BCSub_BallSelectScrnWrite(wk,FALSE);
		BCSub_YesNoBtnSet(wk);
		wk->seq++;
		break;
	case 3:
		//YesNoボタン待ち
		ret = BCSub_YesNoBtnWait(wk);
		if(ret < 0){
			break;
		}
		wk->seq = 0;
		if(ret){
			//選んだ
			BonguriSave_KeepBonguri(wk->bong_sv,wk->target,wk->sel_num);
			return SEQ_FADE_OUT;
		}
		BCSub_SetPassivePotMain(wk,BONG_STATE_ACTIVE);
		BCSub_SysMsgPut(wk,MIDX_SYS_BONG01);	//渡すぼんぐりを選んでください
	default:
		wk->seq = 0;
		return SEQ_BALL_MAIN;
	}
	return SEQ_BALL_NUMSET;
}

/**
 *	@brief	ボングリをポット上に移動
 */
static int seq_BongMoveKey(BC_APPWORK* wk)
{
	switch(wk->seq){
	case 0:
		BCSub_SetPassivePotMain(wk,BONG_STATE_TARGET_ONLY);
//		BCSub_BackButtonWrite(wk,BTN_PASSIVE);

		wk->seq++;
		break;
	case 1:
		if(!BCSub_BongCatchEff(wk,TRUE)){
			break;
		}
		BCSub_BongMoveEffSet(wk,MOVE_BONG,MOVE_TO_POT);
		BCSub_BongMoveEffSet(wk,MOVE_CURSOR,MOVE_TO_POT);
		wk->seq++;
		break;
	case 2:
		if(wk->eff_tcb_ct){
			break;
		}
		Snd_SePlay( SE_BC_OPEN );
		CLACT_AnmChg(wk->pAct[ACT_POT_T], ANM_P_OPEN );
		wk->seq++;
	case 3:
		if(sys.trg & PAD_BUTTON_DECIDE){
			wk->seq = 0;
			Snd_SePlay(SE_BC_PUT);
			return SEQ_BONG_POT_SET;
#if 0
		}else if(sys.trg & PAD_BUTTON_CANCEL){
			wk->seq = 0;
			Snd_SePlay(SE_BC_RETURN);
			return SEQ_BONG_MOVE_END;
		}
#else
		}else if((sys.trg & PAD_BUTTON_CANCEL)){
			wk->seq = 0;
			Snd_SePlay(SE_BC_RETURN);
			return SEQ_BONG_MOVE_END;
		}else if(GF_TP_GetTrg()){
			wk->seq = 0;
			Snd_SePlay(SE_BC_RETURN);
			if(wk->key_mode != APP_KTST_TOUCH){
				wk->key_mode = APP_KTST_KEY;
			}
			return SEQ_BONG_MOVE_END;
		}
#endif
		break;
	default:
		wk->seq = 0;
		return SEQ_POT_MAIN;
	}
	return SEQ_BONG_MOVE_KEY;
}

/**
 *	@brief	ボングリをポット上に移動(タッチ)
 */
static int seq_BongMoveTouch(BC_APPWORK* wk)
{
	int ret;

	switch(wk->seq){
	case 0:
		BCSub_SetPassivePotMain(wk,BONG_STATE_TARGET_ONLY);
		wk->seq++;
		break;
	case 1:
		if(!BCSub_BongCatchEff(wk,TRUE)){
			break;
		}
		wk->seq++;
		break;
	case 2:
		ret = BCKey_InputBongMoveTouch(wk);
		switch(ret){
		case 0:
			wk->seq = 0;
			return SEQ_BONG_MOVE_END;
		case 1:
			wk->seq = 0;
			return SEQ_BONG_POT_SET;
		default:
			break;
		}
		break;
	default:
		break;
	}
	return SEQ_BONG_MOVE_TOUCH;
}

/**
 *	@brief	掴んだボングリをリリース
 */
static int seq_BongMoveEnd(BC_APPWORK* wk)
{
	switch(wk->seq){
	case 0:
		BCSub_BongMoveEffSet(wk,MOVE_BONG,MOVE_TO_BONG);
		BCSub_BongMoveEffSet(wk,MOVE_CURSOR,MOVE_TO_BONG);
		//Snd_SePlay( SE_BC_CLOSE );						//ポットの上、それ以外でも処理が通る
		CLACT_AnmChg(wk->pAct[ACT_POT_T], ANM_P_CLOSE );
		wk->seq++;
		break;
	case 1:
		if(wk->eff_tcb_ct){
			break;
		}
		wk->seq++;
		break;
	case 2:
		if(!BCSub_BongCatchEff(wk,FALSE)){
			break;
		}
	default:
		BCSub_SetPassivePotMain(wk,BONG_STATE_ACTIVE);
//		BCSub_BackButtonWrite(wk,BTN_ACTIVE);
		wk->seq = 0;
		return SEQ_POT_MAIN;
	}
	return SEQ_BONG_MOVE_END;
}

/**
 *	@brief	ボングリをポットにセット
 */
static int seq_BongPotSet(BC_APPWORK* wk)
{
	switch(wk->seq){
	case 0:
		if(wk->bong.stock_num >= BONGJUICE_STOCK_MAX){
			BCSub_SysMsgPut(wk,MIDX_SYS_STOCK02);
			BCSub_TalkMsgPut(wk,MIDX_TALK_POT_FULL,MSG_NO_PUT);
			wk->seq = 1;
		}else{
			//ボングリをストック
			wk->cpos_x = CLINE_C;
			wk->cpos_y = 0;
			wk->seq = 2;
		}
		break;
	case 1:	//もう入らないとき
		if(!sub_MsgWait(wk)){
			break;
		}
		BCSub_TalkMsgClear(wk);
		wk->seq = 0;
		return SEQ_BONG_MOVE_END;
	case 2:	//入れたとき
		if(!BCSub_BongCatchEff(wk,FALSE)){
			break;
		}
		CLACT_SetDrawFlag(wk->pAct[ACT_BONG01+wk->target],FALSE);
		CLACT_AnmChg(wk->pAct[ACT_POT_T],ANM_PA_CLOSE);
		CLACT_AnmReStart(wk->pAct[ACT_POT_T]);
		wk->seq++;
		break;
	case 3:
		if( CLACT_AnmActiveCheck( wk->pAct[ACT_POT_T] )){
			break;
		}
		Snd_SePlay( SE_BC_CLOSE );
		CLACT_AnmChg(wk->pAct[ACT_POT_T], ANM_P_CLOSE );

		BonguriSave_SetStock(wk->bong_sv,wk->target,wk->now_walk_ct);
		BCSub_BongDataUpdate(wk);
		BCSub_BongMoveEffSet(wk,MOVE_CURSOR,MOVE_TO_POT);
		wk->seq++;
		break;
	case 4:
		if(wk->eff_tcb_ct){
			break;
		}
		if(wk->bong.stock_num >= BONGJUICE_STOCK_MAX){
			BCSub_SysMsgPut(wk,MIDX_SYS_STOCK02);
		}else{
			BCSub_SysMsgPut(wk,MIDX_SYS_STOCK01);
		}
		BCSub_BongNumWinWrite(wk,wk->target);
		BCSub_SetPassivePotMain(wk,BONG_STATE_ACTIVE);
//		BCSub_BackButtonWrite(wk,BTN_ACTIVE);
		wk->seq = 0;
		return SEQ_POT_MAIN;
	}
	return SEQ_BONG_POT_SET;
}

/**
 *	@brief	ジュースに対するコマンドリスト
 */
static int seq_ListJuice(BC_APPWORK* wk)
{
	u32 ret;

	switch(wk->seq){
	case 0:
		BCSub_SBoxSet(wk);
		BCSub_SysMsgPut(wk,MIDX_SYS_JUICE);
		BCSub_SetPassivePotMain(wk,BONG_STATE_PASSIVE);
		wk->seq++;
		break;
	case 1:
		ret = BCSub_SBoxWait( wk );
		if(ret == SBOX_SELECT_NULL ){
			break;
		}
		wk->seq = 0;
		if(ret >= 2 || ret == SBOX_SELECT_CANCEL){
			BCSub_SysMsgPotStSet(wk);
			return SEQ_POT_MAIN;
		}else if(ret == 1){	//味見
			BCSub_SysMsgPut(wk,MIDX_SYS_TASTE);
			BCSub_TalkMsgTastingPut(wk);
			BCSub_SetPassivePotMain(wk,BONG_STATE_PASSIVE);
			return SEQ_TALKMSG_WAIT;
		}
		//使う
		wk->sp->mode = SYSMODE_PLIST;
		wk->sp->ret_poke = 0;
		wk->sp->ret_cpos_a = wk->opos_a;
		wk->sp->ret_cpos_b = wk->opos_b;
		return SEQ_FADE_OUT;
	}
	return SEQ_LIST_JUICE;
}

/**
 *	@brief 書き切りメッセージ待ち
 */
static int seq_MsgWait(BC_APPWORK* wk)
{
	if(sub_MsgWait(wk)){
//		BCSub_MsgPut(wk,MIDX_POT_MAIN,BED_NULL,TRUE);
//		BCSub_ActAnmControl(wk,TRUE);
		return SEQ_POT_MAIN;
	}
	return SEQ_MSG_WAIT;
}

/**
 *	@brief	会話メッセージ待ちサブ
 */
static int seq_TalkMsgWait(BC_APPWORK* wk)
{
	if(sub_MsgWait(wk)){
		BCSub_TalkMsgClear(wk);
		BCSub_SysMsgPotStSet(wk);
		return SEQ_POT_MAIN;
	}
	return SEQ_TALKMSG_WAIT;
}

/**
 *	@brief	メッセージ待ちサブ
 */
static BOOL sub_MsgWait(BC_APPWORK* wk)
{
	if(wk->msg_idx != 0xFF){
		if( GF_MSG_PrintEndCheck( wk->msg_idx ) ){
			return FALSE;
		}
	}
	if( GF_TP_GetTrg()){
		Snd_SePlay( SE_BC_DECIDE );
		wk->key_mode = APP_KTST_TOUCH;
		MsgPrintTouchPanelFlagSet( MSG_TP_OFF );
		wk->msg_idx = 0xFF;
		return TRUE;
	}
	if(sys.trg & PAD_BUTTON_KTST_CHG){
		wk->key_mode = APP_KTST_KEY;
	}
	if(sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL)){
		Snd_SePlay( SE_BC_DECIDE );
		MsgPrintTouchPanelFlagSet( MSG_TP_OFF );
		wk->msg_idx = 0xFF;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	画面初期化
 */
static void sub_ViewClear(void)
{
	sys_VBlankFuncChange(NULL, NULL);
	sys_HBlankIntrStop();	//HBlank割り込み停止

	GF_Disp_GX_VisibleControlInit();
	GF_Disp_GXS_VisibleControlInit();
	GX_SetVisiblePlane(0);
	GXS_SetVisiblePlane(0);

	WIPE_SetBrightness(WIPE_DISP_MAIN,WIPE_FADE_BLACK);
	WIPE_SetBrightness(WIPE_DISP_SUB,WIPE_FADE_BLACK);
	WIPE_ResetWndMask(WIPE_DISP_MAIN);
	WIPE_ResetWndMask(WIPE_DISP_SUB);
}
